﻿using System;
using System.Collections.Generic;
using Microsoft.SystemCenter.Orchestrator.Integration;
using RestSharp;
using SocialMediaIntegrationPack.Properties;

namespace SocialMediaIntegrationPack
{
    [Activity("GetYammerMessages")]
    public class YammerGetMessagesAct : YammerActivity
    {
        private readonly int defLimit = 20;
        private readonly int yammerLimit = 20;
        private readonly string pname_older_than = "older_than";
        private readonly string pname_limit = "limit";

        [ActivityInput("Limit(1-220)",Default = "20")]
        public string Limit { get; set; }

        [ActivityInput("Messages Type", Default = "All", Options = "All,Sent,Received,Private,Following,From_UserID,In_GroupID,About_TopicID,Liked_ByID,In_ThreadID")]
        public string Type { get; set; }

        [ActivityOutput]
        public int MessagesFound { get; set; }

        /// <summary>
        /// Mapping table of Yammer resources available via REST
        /// </summary>
        private readonly Dictionary<string, string> resourceMapping = new Dictionary<string, string>
        {
            { "Sent",           "api/v1/messages/sent.json" },
            { "Received",       "api/v1/messages/received.json" },
            { "Private",        "api/v1/messages/private.json" },
            { "Following",      "api/v1/messages/following.json" },
            { "From_UserID",    "api/v1/messages/from_user/{0}.json" },
            { "In_GroupID",     "api/v1/messages/in_group/{0}.json" },
            { "About_TopicID",  "api/v1/messages/about_topic/{0}.json" },
            { "Liked_ByID",     "api/v1/messages/liked_by/{0}.json" },
            { "In_ThreadID",    "api/v1/messages/in_thread/{0}.json" },
            { string.Empty,     "api/v1/messages.json" }
        };

        /// <summary>
        /// Return REST resource address based on current Type
        /// </summary>
        private string GetResource()
        {
            string resource;
            if (!resourceMapping.TryGetValue(Type, out resource))
                resource = resourceMapping[String.Empty];

            if (resource.IsFormat())
            {
                CheckId();
                resource = String.Format(resource, Id);
            }

            return resource;
        }

        protected virtual void AddRequestExtraParameters(RestRequest r)
        {
        }

        protected virtual List<YammerMessage> FilterMessages(List<YammerMessage> lst)
        {
            return lst;
        }


        /// <summary>
        /// Getting messages till limit by twenty - yammer limitation
        /// </summary>
        [ActivityMethod]
        public void Execute()
        {
            var client = GetClient(Configuration.AccessToken, Configuration.AccessTokenSecret);
            var request = new RestRequest(GetResource(), Method.GET);
            long lmt = defLimit; 

            if (!String.IsNullOrEmpty(Limit) && (!Int64.TryParse(Limit, out lmt) || lmt <= 0 || lmt > 220))
            {
                throw new ArgumentOutOfRangeException(Resources.INCORRECT_LIMIT);
            }

            Messages = new List<YammerMessage>();
            long get_plan = 0;
            long get_fact = 0;
            RestResponse<YammerMessages> temp;
            List<YammerMessage> flt;
            Parameter olderparam = null;
            do
            {
                AddRequestExtraParameters(request);

                if (Messages.Count > 0)
                {
                    if (olderparam == null)
                    {
                        olderparam = new Parameter();
                        olderparam.Name = pname_older_than;
                        request.AddParameter(olderparam);
                    }
                    olderparam.Value = Messages[Messages.Count - 1].Id;
                }

                get_plan = lmt - Messages.Count;
                if (get_plan < yammerLimit && get_plan > 0) // need to get less than yammer limit
                {
                    request.AddParameter(pname_limit, get_plan);
                }
                else
                {
                    get_plan = yammerLimit;
                }

                temp = client.Execute<YammerMessages>(request);
                CheckResponse(temp);
                if (temp.Data != null && temp.Data.Messages != null)
                {
                    get_fact = temp.Data.Messages.Count;

                    flt = FilterMessages(temp.Data.Messages);
                    Messages.AddRange(flt);
                }
                else
                {
                    get_fact = 0;
                }
            } while (Messages.Count < lmt && get_fact == yammerLimit); // need more messages and there are more messages
            MessagesFound = (Int32)Messages.Count;
            Response = string.Format(Resources.YammerGetMsgsAct_Run_Found_msgs, MessagesFound);
        }

    }
}
